home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
gnu
/
flex
/
flexs237.zoo
/
parse.y
< prev
next >
Wrap
Text File
|
1990-06-28
|
14KB
|
703 lines
/* parse.y - parser for flex input */
%token CHAR NUMBER SECTEND SCDECL XSCDECL WHITESPACE NAME PREVCCL EOF_OP
%{
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Vern Paxson.
*
* The United States Government has rights in this work pursuant
* to contract no. DE-AC03-76SF00098 between the United States
* Department of Energy and the University of California.
*
* Redistribution and use in source and binary forms are permitted provided
* that: (1) source distributions retain this entire copyright notice and
* comment, and (2) distributions including binaries display the following
* acknowledgement: ``This product includes software developed by the
* University of California, Berkeley and its contributors'' in the
* documentation or other materials provided with the distribution and in
* all advertising materials mentioning features or use of this software.
* Neither the name of the University nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static char rcsid[] =
"@(#) $Header: /usr/fsys/odin/a/vern/flex/RCS/parse.y,v 2.7 90/06/27 23:48:31 vern Exp $ (LBL)";
#endif
#include "flexdef.h"
int pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, actvp, rulelen;
int trlcontxt, xcluflg, cclsorted, varlength, variable_trail_rule;
Char clower();
static int madeany = false; /* whether we've made the '.' character class */
int previous_continued_action; /* whether the previous rule's action was '|' */
%}
%%
goal : initlex sect1 sect1end sect2 initforrule
{ /* add default rule */
int def_rule;
pat = cclinit();
cclnegate( pat );
def_rule = mkstate( -pat );
finish_rule( def_rule, false, 0, 0 );
for ( i = 1; i <= lastsc; ++i )
scset[i] = mkbranch( scset[i], def_rule );
if ( spprdflt )
fputs( "YY_FATAL_ERROR( \"flex scanner jammed\" )",
temp_action_file );
else
fputs( "ECHO", temp_action_file );
fputs( ";\n\tYY_BREAK\n", temp_action_file );
}
;
initlex :
{
/* initialize for processing rules */
/* create default DFA start condition */
scinstal( "INITIAL", false );
}
;
sect1 : sect1 startconddecl WHITESPACE namelist1 '\n'
|
| error '\n'
{ synerr( "unknown error processing section 1" ); }
;
sect1end : SECTEND
;
startconddecl : SCDECL
{
/* these productions are separate from the s1object
* rule because the semantics must be done before
* we parse the remainder of an s1object
*/
xcluflg = false;
}
| XSCDECL
{ xcluflg = true; }
;
namelist1 : namelist1 WHITESPACE NAME
{ scinstal( nmstr, xcluflg ); }
| NAME
{ scinstal( nmstr, xcluflg ); }
| error
{ synerr( "bad start condition list" ); }
;
sect2 : sect2 initforrule flexrule '\n'
|
;
initforrule :
{
/* initialize for a parse of one rule */
trlcontxt = variable_trail_rule = varlength = false;
trailcnt = headcnt = rulelen = 0;
current_state_type = STATE_NORMAL;
previous_continued_action = continued_action;
new_rule();
}
;
flexrule : scon '^' rule
{
pat = $3;
finish_rule( pat, variable_trail_rule,
headcnt, trailcnt );
for ( i = 1; i <= actvp; ++i )
scbol[actvsc[i]] =
mkbranch( scbol[actvsc[i]], pat );
if ( ! bol_needed )
{
bol_needed = true;
if ( performance_report )
pinpoint_message(
"'^' operator results in sub-optimal performance" );
}
}
| scon rule
{
pat = $2;
finish_rule( pat, variable_trail_rule,
headcnt, trailcnt );
for ( i = 1; i <= actvp; ++i )
scset[actvsc[i]] =
mkbranch( scset[actvsc[i]], pat );
}
| '^' rule
{
pat = $2;
finish_rule( pat, variable_trail_rule,
headcnt, trailcnt );
/* add to all non-exclusive start conditions,
* including the default (0) start condition
*/
for ( i = 1; i <= lastsc; ++i )
if ( ! scxclu[i] )
scbol[i] = mkbranch( scbol[i], pat );
if ( ! bol_needed )
{
bol_needed = true;
if ( performance_report )
pinpoint_message(
"'^' operator results in sub-optimal performance" );
}
}
| rule
{
pat = $1;
finish_rule( pat, variable_trail_rule,
headcnt, trailcnt );
for ( i = 1; i <= lastsc; ++i )
if ( ! scxclu[i] )
scset[i] = mkbranch( scset[i], pat );
}
| scon EOF_OP
{ build_eof_action(); }
| EOF_OP
{
/* this EOF applies to all start conditions
* which don't already have EOF actions
*/
actvp = 0;
for ( i = 1; i <= lastsc; ++i )
if ( ! sceof[i] )
actvsc[++actvp] = i;
if ( actvp == 0 )
pinpoint_message(
"warning - all start conditions already have <<EOF>> rules" );
else
build_eof_action();
}
| error
{ synerr( "unrecognized rule" ); }
;
scon : '<' namelist2 '>'
;
namelist2 : namelist2 ',' NAME
{
if ( (scnum = sclookup( nmstr )) == 0 )
format_pinpoint_message(
"undeclared start condition %s", nmstr );
else
actvsc[++actvp] = scnum;
}
| NAME
{
if ( (scnum = sclookup( nmstr )) == 0 )
format_pinpoint_message(
"undeclared start condition %s", nmstr );
else
actvsc[actvp = 1] = scnum;
}
| error
{ synerr( "bad start condition list" ); }
;
rule : re2 re
{
if ( transchar[lastst[$2]] != SYM_EPSILON )
/* provide final transition \now/ so it
* will be marked as a trailing context
* state
*/
$2 = link_machines( $2, mkstate( SYM_EPSILON ) );
mark_beginning_as_normal( $2 );
current_state_type = STATE_NORMAL;
if ( previous_continued_action )
{
/* we need to treat this as variable trailing
* context so that the backup does not happen
* in the action but before the action switch
* statement. If the backup happens in the
* action, then the rules "falling into" this
* one's action will *also* do the backup,
* erroneously.
*/
if ( ! varlength || headcnt != 0 )
{
fprintf( stderr,
"%s: warning - trailing context rule at line %d made variable because\n",
program_name, linenum );
fprintf( stderr,
" of preceding '|' action\n" );
}
/* mark as variable */
varlength = true;
headcnt = 0;
}
if ( varlength && headcnt == 0 )
{ /* variable trailing context rule */
/* mark the first part of the rule as the accepting
* "head" part of a trailing context rule
*/
/* by the way, we didn't do this at the beginning
* of this production because back then
* current_state_type was set up for a trail
* rule, and add_accept() can create a new
* state ...
*/
add_accept( $1, num_rules | YY_TRAILING_HEAD_MASK );
variable_trail_rule = true;
}
else
trailcnt = rulelen;
$$ = link_machines( $1, $2 );
}
| re2 re '$'
{ synerr( "trailing context used twice" ); }
| re '$'
{
if ( trlcontxt )
{
synerr( "trailing context used twice" );
$$ = mkstate( SYM_EPSILON );
}
else if ( previous_continued_action )
{
/* see the comment in the rule for "re2 re"
* above
*/
if ( ! varlength || headcnt != 0 )
{
fprintf( stderr,
"%s: warning - trailing context rule at line %d made variable because\n",
program_name, linenum );
fprintf( stderr,